import React, { Component } from 'react'
import axios from 'axios'
import PubSub from 'pubsub-js'

import './List.css'

export default class List extends Component {


  state = {
    // 是否第一次查询
    initQuery: true,
    loading: false,
    userList: [],
    failed: false
  }
  componentDidMount() {
    // 订阅消息
    this.token = PubSub.subscribe('keywords', async (msg, keywords) => {
      // 更改状态为搜索中
      this.setState({
        initQuery: false,
        loading: true
      })
      // 请求地址
      const url = `https://api.github.com/search/users?q=${keywords}`
      try {
        const response = await axios.get(url)
        const result = response.data;

        this.setState({
          userList: result.items.map(user => (
            {
              name: user.login,
              pic: user.avatar_url,
              html_url: user.html_url
            }
          )),
          loading: false,
          failed: false
        })
      } catch (error) {
        this.setState({
          failed: true,
          loading: false
        })
      }
    })
  }
  // 组件将要被卸载的时候
  componentWillUnmount(){
    // 在组件即将被卸载的时候，取消订阅
    PubSub.unsubscribe(this.token)
  }
  render() {
    const { initQuery, loading, userList, failed } = this.state;
    if (initQuery) {
      return <h1>请输入用户名进行搜索</h1>
    } else if (loading) {
      return <h1>加载中</h1>
    } else if (failed) {
      return <h1>搜索失败</h1>
    } else {
      return (
        <div className="row">
          {
            userList.map(user => (
              <div className="card" key={user.name}>
                <a href={user.html_url} target="blank">
                  <img src={user.pic} alt={user.name} style={{ width: 100 }} />
                </a>
                <p className="card-text">{user.name}</p>
              </div>
            ))
          }
        </div>
      )
    }

  }
}

/*
  理解并使用 async/ await
  1. 理解
    具体说： 简化 promise 的使用，不用再通过 then() / catch() 来指定回调函数
    抽象说： 以同步编码实现异步流程
  2. 使用 await
    在返回 promise 的表达式左侧使用， 不想要 promise, 而要得到其异步执行返回的成功结果
  3. 使用 async
    在 await 最近的函数定义左侧
*/